<?
class GOOGLE_CHARTS {
    protected $URL = 'https://chart.googleapis.com/chart';
    protected $Labels = array();
    protected $Data = array();
    protected $Options = array();

    public function __construct($Type, $Width, $Height, $Options) {
        if ($Width * $Height > 300000 || $Height > 1000 || $Width > 1000) {
            trigger_error('Tried to make chart too large.');
        }
        $this->URL .= "?cht=$Type&amp;chs={$Width}x$Height";
        $this->Options = $Options;
    }

    protected function encode($Number) {
        if ($Number == -1) {
            return '__';
        }
        $CharKey = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';
        return $CharKey[floor($Number / 64)] . $CharKey[floor($Number % 64)];
    }

    public function color($Colors) {
        $this->URL .= '&amp;chco=' . $Colors;
    }

    public function lines($Thickness, $Solid = 1, $Blank = 0) {
        $this->URL .= "&amp;chls=$Thickness,$Solid,$Blank";
    }

    public function title($Title, $Color = '', $Size = '') {
        $this->URL .= '&amp;chtt=' . str_replace(array(' ', "\n"), array('+', '|'), $Title);
        if (!empty($Color)) {
            $this->URL .= '&amp;chts=' . $Color;
        }
        if (!empty($Size)) {
            $this->URL .= ',' . $Size;
        }
    }

    public function legend($Items, $Placement = '') {
        $this->URL .= '&amp;chdl=' . str_replace(' ', '+', implode('|', $Items));
        if (!empty($Placement)) {
            if (!in_array($Placement, array('b', 't', 'r', 'l', 'bv', 'tv'))) {
                trigger_error('Invalid legend placement.');
            }
            $this->URL .= '&amp;chdlp=' . $Placement;
        }
    }

    public function add($Label, $Data) {
        if ($Label !== false) {
            $this->Labels[] = $Label;
        }
        $this->Data[] = $Data;
    }

    public function grid_lines($SpacingX = 0, $SpacingY = -1, $Solid = 1, $Blank = 1) {
        //Can take 2 more parameters for offset, but we're not bothering with that right now
        $this->URL .= "&amp;chg=$SpacingX,$SpacingY,$Solid,$Blank";
    }

    public function transparent() {
        $this->URL .= '&amp;chf=bg,s,FFFFFF00';
    }


    public function url() {
        return $this->URL;
    }
}

class AREA_GRAPH extends GOOGLE_CHARTS {
    public function __construct($Width, $Height, $Options = array()) {
        parent::__construct('lc', $Width, $Height, $Options);
    }

    public function color($Color) {
        $this->URL .= '&amp;chco=' . $Color . '&amp;chm=B,' . $Color . '50,0,0,0';
    }

    public function generate() {
        $Max = max($this->Data);
        $Min = ((isset($this->Options['Break'])) ? $Min = min($this->Data) : 0);
        $Data = array();
        foreach ($this->Data as $Value) {
            $Data[] = $this->encode((($Value - $Min) / ($Max - $Min)) * 4095);
        }
        $this->URL .= "&amp;chxt=y,x&amp;chxs=0,h&amp;chxl=1:|" . implode('|', $this->Labels) . '&amp;chxr=0,' . $Min . ',' . ($Max - $Min) . '&amp;chd=e:' . implode('', $Data);
    }
}

class PIE_CHART extends GOOGLE_CHARTS {
    public function __construct($Width, $Height, $Options = array()) {
        $Type = ((isset($this->Options['3D'])) ? 'p3' : 'p');
        parent::__construct($Type, $Width, $Height, $Options);
    }

    public function generate() {
        $Sum = array_sum($this->Data);
        $Other = isset($this->Options['Other']);
        $Sort = isset($this->Options['Sort']);
        $LabelPercent = isset($this->Options['Percentage']);

        if ($Sort && !empty($this->Labels)) {
            array_multisort($this->Data, SORT_DESC, $this->Labels);
        } elseif ($Sort) {
            sort($this->Data);
            $this->Data = array_reverse($this->Data);
        }

        $Data = array();
        $Labels = $this->Labels;
        $OtherPercentage = 0.00;
        $OtherData = 0;

        foreach ($this->Data as $Key => $Value) {
            $ThisPercentage = number_format(($Value / $Sum) * 100, 2);
            $ThisData = ($Value / $Sum) * 4095;
            if ($Other && $ThisPercentage < 1) {
                $OtherPercentage += $ThisPercentage;
                $OtherData += $ThisData;
                unset($Data[$Key]);
                unset($Labels[$Key]);
                continue;
            }
            if ($LabelPercent) {
                $Labels[$Key] .= ' (' . $ThisPercentage . '%)';
            }
            $Data[] = $this->encode($ThisData);
        }
        if ($OtherPercentage > 0) {
            $OtherLabel = 'Other';
            if ($LabelPercent) {
                $OtherLabel .= ' (' . $OtherPercentage . '%)';
            }
            $Labels[] = $OtherLabel;
            $Data[] = $this->encode($OtherData);
        }
        $this->URL .= "&amp;chl=" . implode('|', $Labels) . '&amp;chd=e:' . implode('', $Data);
    }
}


class LOG_BAR_GRAPH extends GOOGLE_CHARTS {
    //TODO: Finish.
    public function __construct($Base, $Width, $Height, $Options = array()) {
        parent::__construct('lc', $Width, $Height, $Options);
    }

    public function color($Color) {
        $this->URL .= '&amp;chco=' . $Color . '&amp;chm=B,' . $Color . '50,0,0,0';
    }

    public function generate() {
        $Max = max($this->Data);
        $Min = ((isset($this->Options['Break'])) ? $Min = min($this->Data) : 0);
        $Data = array();
        foreach ($this->Data as $Value) {
            $Data[] = $this->encode((($Value - $Min) / ($Max - $Min)) * 4095);
        }
        $this->URL .= "&amp;chxt=y,x&amp;chxs=0,h&amp;chxl=1:|" . implode('|', $this->Labels) . '&amp;chxr=0,' . $Min . ',' . ($Max - $Min) . '&amp;chd=e:' . implode('', $Data);
    }
}

class POLL_GRAPH extends GOOGLE_CHARTS {
    public function __construct() {
        $this->URL .= '?cht=bhg';
    }

    public function add($Label, $Data) {
        if ($Label !== false) {
            $this->Labels[] = Format::cut_string($Label, 35);
        }
        $this->Data[] = $Data;
    }

    public function generate() {
        $Count = count($this->Data);
        $Height = (30 * $Count) + 20;
        $Max = max($this->Data);
        $Sum = array_sum($this->Data);
        $Increment = ($Max / $Sum) * 25; // * 100% / 4divisions
        $Data = array();
        $Labels = array();
        foreach ($this->Data as $Key => $Value) {
            $Data[] = $this->encode(($Value / $Max) * 4095);
            $Labels[] = '@t' . str_replace(array(' ', ','), array('+', '\,'), $this->Labels[$Key]) . ',000000,1,' . round((($Key + 1) / $Count) - (12 / $Height), 2) . ':0,12';
        }
        $this->URL .= "&amp;chbh=25,0,5&amp;chs=214x$Height&amp;chl=0%|" . round($Increment, 1) . "%|" . round($Increment * 2, 1) . "%|" . round($Increment * 3, 1) . "%|" . round($Increment * 4, 1) . "%&amp;chm=" . implode('|', $Labels) . '&amp;chd=e:' . implode('', $Data);
    }
}
